// SysInit Unit
// Modular Support - BPL

(*************)
(* Interface *)
(*************)
{$IFDEF Include_Modules_Header}

 Procedure _PackageLoad(Const ModuleInfo: TModuleInfo);
 Procedure _PackageUnload(Const ModuleInfo: TModuleInfo);

 Function _InitPkg(AHInst: NativeUInt; Reason: Integer; Reserved: Pointer): LongBool; StdCall;

{$ENDIF Include_Modules_Header}
(******************)
(* Implementation *)
(******************)
{$IFDEF Include_Modules_Implement}

 // Dynamic loaded package gets this call (to initialize all units)
 Procedure _PackageLoad(Const ModuleInfo: TModuleInfo);
  BEGIN
   _INT_Module.ModuleInfo:= @ModuleInfo;
   System.ModuleInit(@_INT_Module);
  END;

 // Dynamic loaded package gets this call (to finalize all units)
 Procedure _PackageUnload(Const ModuleInfo: TModuleInfo);
  BEGIN
   System.ModuleFInit(@_INT_Module);
  END;

 ResourceString
  _RTL_ResStr_ContextPackageMain = 'Package Entry Function - ';

 // This is the package entry point (DLLMain) for static binding and dynamic loading
 // Note: Static binded package are considered part of the EXE/DLL, so the
 //  internal units are initialized and finalized with the EXE/DLL.
 Function _InitPkg(AHInst: NativeUInt; Reason: Integer; Reserved: Pointer): LongBool;
  Procedure DoPackageAttach;
   BEGIN
    Try
     IF @TLSLast <> NIL then _INT_TLSProc[Reason];
     System.RegisterModule(@_INT_Module);
    Except
     _INT_LogEntryException(@_RTL_ResStr_ContextPackageMain, Reason);
     Result:= False;
    END;
   END;

  Procedure DoPackageDetach;
   BEGIN
    Try
     System.UnregisterModule(@_INT_Module);
     IF @TLSLast <> NIL then _INT_TLSProc[Reason];
    Except
     _INT_LogEntryException(@_RTL_ResStr_ContextPackageMain, Reason);
    END;
   END;

  Procedure DoThreadTLS;
   BEGIN
    Try
     IF @TLSLast <> NIL then _INT_TLSProc[Reason];
    Except
     _INT_LogEntryException(@_RTL_ResStr_ContextPackageMain, Reason);
     Raise;
    END;
   END;

  BEGIN
   Result:= True;

   Case Reason of
    _INT_DLL_PROCESS_ATTACH:
     BEGIN
      System._RTL_FirstChanceInit;

      _INT_ModuleType:= mtPackage;
      _INT_HInstance:= AHInst;
      _INT_Module.Instance:= AHInst;

      _INT_InitExtensionStore;
      DoPackageAttach;
     END;

    _INT_DLL_PROCESS_DETACH:
     // If Reserved is assigned, then the current process is being terminated,
     // and thus no further action should be performed, unless it is a signaled safe shutdown.
     IF NOT Assigned(Reserved) OR System._RTL_SafeShutdown
     then DoPackageDetach;

    else DoThreadTLS;
   END;
  END;

{$ENDIF Include_Modules_Implement}

